package com.loser.excel.aspect;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.loser.excel.constant.CMSExcelExportException;
import com.loser.excel.constant.IExcelExportTypes;
import com.loser.excel.core.ExcelExportParams;
import com.loser.excel.utils.ExceptionUtils;
import com.loser.redis.core.RedisHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import java.util.List;
import java.util.Objects;

/**
 * 导出切面
 *
 * @author alan
 * @date 2022/6/9 20:15
 */
@Aspect
public class ExcelExportAspect {

    private final RedisHandler redisHandler;

    private static final Logger excelExportLog = LogManager.getLogger(ExcelExportAspect.class);

    public ExcelExportAspect(RedisHandler redisHandler) {
        this.redisHandler = redisHandler;
    }

    /**
     * excel大数据量导出切面
     */
    @Pointcut("@annotation(com.loser.excel.constant.CheckExportIsReturn)")
    private void checkExport() {
    }

    @Around(value = "checkExport()")
    public Object checkExportIsReturn(ProceedingJoinPoint pjd) throws Throwable {

        // 01 入参打印
        Object[] args = pjd.getArgs();
        List<Object> params = Lists.newArrayList();
        int page = 0;
        Long taskId = 0L;
        String severBeanName = "";
        String exportUser = "";
        int finishCount = 0;
        for (Object obj : args) {
            if (obj instanceof ExcelExportParams) {
                ExcelExportParams exportPrams = (ExcelExportParams) obj;
                taskId = exportPrams.getTaskId();
                severBeanName = exportPrams.getExportServer().getClass().getSimpleName();
                exportUser = exportPrams.getExportUser();
            }
            if (obj instanceof Integer) {
                page = (int) obj;
            }
            params.add(obj);
        }
        excelExportLog.info("01 easyPoiExport severBeanName:{} params:{} exportUser:{}",
                severBeanName, JSONObject.toJSONString(params), exportUser);
        // 02 导出手动中断业务判断
        if (Objects.isNull(taskId)) {
            ExceptionUtils.fail("工单id为空");
        }

        String key = String.format(IExcelExportTypes.STOP_EXPORT_KEY, taskId);
        try {
            if (redisHandler.exists(key)) {
                excelExportLog.info("02 checkExportIsReturn severBeanName:{}", severBeanName);
                redisHandler.del(key);
                throw new CMSExcelExportException("任务已终止");
            }
        } finally {
            redisHandler.del(key);
        }

        // 03 返回值打印
        Object result = pjd.proceed();
        if (result instanceof List) {
            int size = 0;
            if (ObjectUtil.isNotNull(result)) {
                List<?> list = (List<?>) result;
                size = list.size();
            }
            finishCount = size;
            excelExportLog.info("03 easyPoiExport severBeanName:{} page:{} size:{} exportUser:{}", severBeanName, page, size, exportUser);
        } else {
            excelExportLog.info("04 easyPoiExport severBeanName:{} page:{} exportUser:{}", severBeanName, page, exportUser);
        }

        // 04 更新任务的进度
        setTaskProgress(taskId, finishCount);

        return result;


    }

    private void setTaskProgress(Long taskId, int finishCount) {

        Object redisCount = redisHandler.hget(IExcelExportTypes.DOING_EXPORT_KEY, Convert.toStr(taskId));
        if (Objects.nonNull(redisCount)) {
            finishCount = (finishCount + Convert.toInt(redisCount));
        }
        redisHandler.hset(IExcelExportTypes.DOING_EXPORT_KEY, Convert.toStr(taskId), Convert.toStr(finishCount));
        redisHandler.expire(IExcelExportTypes.DOING_EXPORT_KEY, 60);

    }

}
